﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Web;
using System.Text;
using System.Threading.Tasks;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;
using System.Threading;

namespace RestFulService
{

    class Program
    {
        static MqttClient mqttClient;
        /// <summary>
        /// 订阅
        /// </summary>
        public class SubscribeModel
        {
            public string Topic { get; set; }
            public byte Qos { get; set; }
            public ushort MessageId { get; set; }
            public ushort UnsubscribeId { get; set; }
            
            public SubscribeModel(string topic, byte qos)
            {
                this.Topic = topic;
                this.Qos = qos;
            }
            public void Subscribe(MqttClient mqttClient)
            {
                string[] topics = new string[] { this.Topic };
                byte[] qos = new byte[] { this.Qos };
                this.MessageId = mqttClient.Subscribe(topics, qos);

            }
            public void Unsubscribe(MqttClient mqttClient)
            {
                string[] topics = new string[] { this.Topic };
                this.UnsubscribeId = mqttClient.Unsubscribe(topics);
            }
            public override string ToString()
            {
                return "主题：" + this.Topic + ",质量：" + this.Qos + ",消息ID:" + this.MessageId;
            }
        }


        static void doLogin()
        {
            string UUID= Guid.NewGuid().ToString();
            try
            {
                mqttClient = new MqttClient("139.224.13.75", 31883, false, null, null, MqttSslProtocols.TLSv1_2);
                mqttClient.ProtocolVersion = MqttProtocolVersion.Version_3_1;
                //mqttClient.ConnectionClosed += MqttClient_ConnectionClosed;
                //mqttClient.MqttMsgPublished += MqttClient_MqttMsgPublished;
                mqttClient.MqttMsgPublishReceived += MqttClient_MqttMsgPublishReceived;
                //mqttClient.MqttMsgSubscribed += MqttClient_MqttMsgSubscribed;
                //mqttClient.MqttMsgUnsubscribed += MqttClient_MqttMsgUnsubscribed;

                byte success = mqttClient.Connect(UUID, "YilunSmart", "YS987789");
                if (success != 0 && mqttClient.IsConnected)
                {
                    //this.MsgBox("连接失败！");
                    Console.WriteLine("连接失败：");
                }
                else
                {
                    Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "MQTT_TITLE:mtopic/order/m5002915ea207");
                    if (mqttClient != null)
                    {
                        //SubscribeModel subscribeModel = new SubscribeModel(this.txtSubscribe.Text, MqttMsgBase.QOS_LEVEL_AT_LEAST_ONCE);
                        SubscribeModel subscribeModel = new SubscribeModel("mtopic/order/m0987654321qwer", MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE);

                        subscribeModel.Subscribe(mqttClient);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "MQTT连接失败：" + ex.Message);
            }
        }

        static void MqttClient_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            byte[] bys = e.Message;
            string content = Encoding.Default.GetString(bys);
            string topic = e.Topic;
            bool dupFlag = e.DupFlag;
            byte qosLevel = e.QosLevel;
            bool retain = e.Retain;

            //使用线程 担心线程启动多个
            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "接收时间：" + DateTime.Now.ToString());
            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "主题：" + topic);
            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "内容：" + content);

            if (content.Equals("1"))
            {
                //创建ThreadStart委托实例
                ThreadStart TS = new ThreadStart(MyThread1);
                //创建Thread类的实例
                Thread thread = new Thread(TS);
                thread.Start();
            }
            else if (content.Equals("2"))
            {
                //创建ThreadStart委托实例
                ThreadStart TS = new ThreadStart(MyThread2);
                //创建Thread类的实例
                Thread thread = new Thread(TS);
                thread.Start();
            }
        }

        //线程函数
        static void MyThread1()
        {
            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "开始缓存redis..." );
            myredis red = new myredis();
            red.doSQLToRedis();
            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "完成缓存redis...");
        }

        static void MyThread2()
        {
            //Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "开始缓存sqlite...");
            Global myGlobal = new Global();
            myGlobal.doSetDB();
            //Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + ":" + "完成缓存sqlite...");
        }

        [STAThread]
        //https://www.cnblogs.com/xuliangxing/p/8735552.html
        //https://learn.microsoft.com/en-us/previous-versions/sql/sql-server-2012/hh510390(v=sql.110)
        //https://tool.4xseo.com/article/458367.html
        static void Main(string[] args)
        {
            try
            {
                Console.Title = "Restful_Server(8220)V1.0.2.9";
                //PersonInfoQueryServices service = new PersonInfoQueryServices();
                //Uri baseAddress = new Uri("http://127.0.0.1:8220/");
                //using (ServiceHost _serviceHost = new ServiceHost(service, baseAddress))//或者：WebServiceHost _serviceHost = new WebServiceHost(typeof(PersonInfoQueryServices), baseAddress);
                //{
                //    //如果不设置MaxBufferSize,当传输的数据特别大的时候，很容易出现“提示:413 Request Entity Too Large”错误信息,最大设置为20M
                //    WebHttpBinding binding = new WebHttpBinding
                //    {
                //        TransferMode = TransferMode.Buffered,
                //        MaxBufferSize = 2147483647,
                //        MaxReceivedMessageSize = 2147483647,
                //        MaxBufferPoolSize = 2147483647,
                //        ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max,
                //        Security = { Mode = WebHttpSecurityMode.None }
                //    };
                //    _serviceHost.AddServiceEndpoint(typeof(IPersonInfoQuery), binding, baseAddress);
                //   // _serviceHost.Opened += delegate
                //   {
                //       Console.WriteLine("Web服务已开启...");
                //   };
                //    _serviceHost.Open();

                //    Console.WriteLine("输入任意键关闭程序！");
                //    Console.ReadKey();
                //    _serviceHost.Close();
                //}

                Global myGlobal = new Global();

                if (myGlobal.starmqtt == 1)
                {
                    doLogin();
                }

                //myGlobal.doSetDB();

                //ContractDescription cd = new ContractDescription("Calculator");
                //ServiceEndpoint svcEndpoint = new ServiceEndpoint(cd);

                Uri baseAddress = new Uri("http://127.0.0.1:8220/");
                //Uri baseAddress = new Uri("http://192.168.0.73:7788/");
                PersonInfoQueryServices service = new PersonInfoQueryServices();
                ////WebServiceHost _serviceHost = new WebServiceHost(service, new Uri("http://127.0.0.1:7788/"));
                ////或者第二种方法：
                WebServiceHost _serviceHost = new WebServiceHost(typeof(PersonInfoQueryServices), baseAddress);
                //如果不设置MaxBufferSize,当传输的数据特别大的时候，很容易出现“提示:413 Request Entity Too Large”错误信息,最大设置为20M
                WebHttpBinding binding = new WebHttpBinding
                {
                    TransferMode = TransferMode.Buffered,
                    MaxBufferSize = 2147483647,
                    MaxReceivedMessageSize = 2147483647,
                    MaxBufferPoolSize = 2147483647,
                    ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max,
                    Security = { Mode = WebHttpSecurityMode.None }
                };
                // 这里不需要安全验证
                binding.Security.Mode = WebHttpSecurityMode.None;
                binding.OpenTimeout = new TimeSpan(0, 20, 0);
                binding.CloseTimeout = new TimeSpan(0, 20, 0);
                binding.SendTimeout = new TimeSpan(0, 20, 0);
                binding.ReceiveTimeout = new TimeSpan(0, 20, 0);

                _serviceHost.AddServiceEndpoint(typeof(IPersonInfoQuery), binding, baseAddress);

                // Enable Mex
                //ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                //smb.HttpGetEnabled = true;
                //_serviceHost.Description.Behaviors.Add(smb);

                _serviceHost.Open();
                Console.WriteLine("*********(HTTP Server)*********");
                Console.WriteLine("*1.redis                      *");
                Console.WriteLine("*2.sqlite                     *");
                Console.WriteLine("*9.exit                       *");
                Console.WriteLine("*******************************");
                int i = 1;
                while (i == 1)
                {
                    string sinput= Console.ReadLine().ToString();//获取键盘输入的值
                    //Console.WriteLine 输出得到的值
                    if (sinput.Equals("1"))
                    {
                        ////myredis red = new myredis();
                        ////red.doSQLToRedis();
                    }
                    else if (sinput.Equals("2"))
                    {
                        myGlobal.doSetDB();
                    }
                    else if (sinput.Equals("9"))
                    {
                        _serviceHost.Close();
                        i = 0;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Web服务开启失败：{0}\r\n{1}", ex.Message, ex.StackTrace);
                Console.ReadKey();
            }

        }
    }
}
